package cn.lg.soar.system.general.service.impl;

import cn.lg.soar.common.data.dict.IDict;
import cn.lg.soar.common.data.msg.I18n;
import cn.lg.soar.common.util.AssertUtil;
import cn.lg.soar.core.api.IResourceApi;
import cn.lg.soar.database.base.service.impl.BaseServiceImpl;
import cn.lg.soar.system.config.AuthCacheKey;
import cn.lg.soar.system.general.entity.Dict;
import cn.lg.soar.system.general.entity.DictItem;
import cn.lg.soar.system.general.mapper.DictItemMapper;
import cn.lg.soar.system.general.mapper.DictMapper;
import cn.lg.soar.system.general.model.DictItemVo;
import cn.lg.soar.system.general.service.IDictItemService;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;

import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author luguoxiang
 * @date 2021/8/15
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
 */
@CacheEvict(value = AuthCacheKey.DICT_BY_CODE, allEntries = true)
public class DictItemServiceImpl extends BaseServiceImpl<DictItemMapper, DictItem> implements IDictItemService {

    private final DictMapper dictMapper;
    private final IResourceApi resourceApi;

    public DictItemServiceImpl(DictMapper dictMapper, IResourceApi resourceApi) {
        this.dictMapper = dictMapper;
        this.resourceApi = resourceApi;
    }

    @Cacheable(value = AuthCacheKey.DICT_BY_CODE, key = "#typeCode")
    @Override
    public List<DictItemVo> listByCode(String typeCode) {
        Dict dict = dictMapper.selectOne(
                Wrappers.<Dict>lambdaQuery()
                        .select(Dict::getId, Dict::getDisabled)
                        .eq(Dict::getCode, typeCode)
        );
        List<DictItem> list;
        Set<Integer> set;
        if (dict == null) {
            list = new ArrayList<>(32);
            set = Collections.emptySet();
        } else {
            // 禁用的返回空
            if (dict.getDisabled()) {
                return Collections.emptyList();
            }
            // 否则查询
            list = this.list(
                    Wrappers.<DictItem>lambdaQuery()
                            .select(
                                    DictItem::getValue,
                                    DictItem::getLabel,
                                    DictItem::getDisabled,
                                    DictItem::getMetadata,
                                    DictItem::getSort
                            )
                            .eq(DictItem::getDictId, dict.getId())
            );
            set = list.stream().map(DictItem::getValue).collect(Collectors.toSet());
        }
        // 读取系统配置的字典
        IDict<Integer>[] sysDicts = resourceApi.getSysDict(typeCode);
        // 合并数据库和枚举
        for (IDict<Integer> item : sysDicts) {
            // 已有值跳过
            if (set.contains(item.getValue())) {
                continue;
            }
            DictItem data = new DictItem();
            data.setValue(item.getValue());
            data.setLabel(item.getLabel());
            data.setSort(item.getValue());
            list.add(data);
        }
        // 排序
        list.sort(Comparator.comparingInt(DictItem::getSort));
        return list.stream().map(DictItemVo::new).collect(Collectors.toList());
    }

    @Override
    public void updateDisabled(Set<Serializable> ids, boolean disabled) {
        AssertUtil.isTrue(
                update(
                        Wrappers.<DictItem>lambdaUpdate()
                                .set(DictItem::getDisabled, disabled)
                                .in(DictItem::getId, ids)
                ),
                I18n.build(disabled ? "禁用失败" : "启用失败")
        );
    }

    @CacheEvict(value = { AuthCacheKey.DICT_BY_CODE, AuthCacheKey.DICT_TYPE }, allEntries = true)
    @Override
    public void clearCache() {}

}
